{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "ymsq1Lw0VEqT"
      },
      "source": [
        "#  Agents with Human-in-loop and Tool Approval from HumanLayer"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "7V3aV16AmY0K"
      },
      "source": [
        "You can also check this cookbook in colab [here](https://colab.research.google.com/drive/1WF1Z6Ev6kTrifRLXXTTOZz6-QVRuj1uX?usp=sharing)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "OkOJ--aQqJQK"
      },
      "source": [
        "<div class=\"align-center\">\n",
        "  <a href=\"https://www.camel-ai.org/\"><img src=\"https://i.postimg.cc/KzQ5rfBC/button.png\"width=\"150\"></a>\n",
        "  <a href=\"https://discord.camel-ai.org\"><img src=\"https://i.postimg.cc/L4wPdG9N/join-2.png\"  width=\"150\"></a></a>\n",
        "  \n",
        "⭐ <i>Star us on [*Github*](https://github.com/camel-ai/camel), join our [*Discord*](https://discord.camel-ai.org) or follow our [*X*](https://x.com/camelaiorg)\n",
        "</div>"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "G5gE04UuPUWj"
      },
      "source": [
        "This notebook demonstrates how to set up and leverage CAMEL's ability to interact with user (for approval or comments) during the execution of the tasks.\n",
        "\n",
        "In this notebook, you'll explore:\n",
        "\n",
        "*   **CAMEL**: A powerful multi-agent framework that enables Retrieval-Augmented Generation and multi-agent role-playing scenarios, allowing for sophisticated AI-driven tasks.\n",
        "*   **HumanLayer**: HumanLayer is an API and SDK that enables AI Agents to contact humans for feedback, input, and approvals.\n",
        "*   **Human-in-loop**: The ability for agent to consult human during the execution of the task.\n",
        "*   **Human approval**: The ability for agent ask approval to execute some tasks.\n",
        "\n",
        "This cookbook demonstrates how to use **HumanLayer** functionality within CAMEL framework."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "5z_eY54ZzsdQ"
      },
      "source": [
        "![human.png]()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "0J0_iW-YVcq2"
      },
      "source": [
        "## 📦 Installation"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "7p-JjpyNVcCT"
      },
      "source": [
        "First, install the CAMEL package with all its dependencies:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 1000
        },
        "collapsed": true,
        "id": "0GXs2pruU9Vl",
        "outputId": "cbb59504-6ba4-431a-8e30-08c90eb610b8"
      },
      "outputs": [],
      "source": [
        "!pip install \"camel-ai[all]==0.2.16\""
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "rnlxVTLs4spt"
      },
      "source": [
        "Next, install humanlayer python SDK:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "collapsed": true,
        "id": "uEijqcLt4v1b",
        "outputId": "2c04d7a9-e17a-41a1-9539-59224f4d3f6a"
      },
      "outputs": [],
      "source": [
        "!pip install humanlayer"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "lfNvFbhD6o8B"
      },
      "source": [
        "## 🔑 Setting Up API Keys"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "mf9iO_Haua-7"
      },
      "source": [
        "Your can go to [here](https://openai.com/index/openai-api/) to get API Key from OpenAI."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "ZhauVXPOua-8",
        "outputId": "21f991f7-e251-4534-df54-dfc15f54b532"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Enter your API key: ··········\n"
          ]
        }
      ],
      "source": [
        "# Prompt for the API key securely\n",
        "import os\n",
        "from getpass import getpass\n",
        "\n",
        "qwen_api_key = getpass('Enter your API key: ')\n",
        "os.environ[\"QWEN_API_KEY\"] = qwen_api_key"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "rdMup8dLuEJH"
      },
      "source": [
        "Your can go to [here](https://app.humanlayer.dev/auth) to get API Key from HumanLayer."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "qk-JofPGufux",
        "outputId": "25f7813c-ff32-4018-f324-6668abd79045"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Enter your HumanLayer API key: ··········\n"
          ]
        }
      ],
      "source": [
        "humanlayer_api_key = getpass('Enter your HumanLayer API key: ')\n",
        "os.environ[\"HUMANLAYER_API_KEY\"] = humanlayer_api_key"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "NEUciNquON9_"
      },
      "source": [
        "## 👨 Tools that requires human approval"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "6f64VOMMP93d"
      },
      "source": [
        "In this section, we'll demonstrate how to define tools for Camel agent to use, and use **HumanLayer** to make some tools require human approval. First define two functions for agent to use, one of them requires human approval."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 14,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "m14JurOf6mQr",
        "outputId": "e3ee90fd-ca9f-4255-c929-cd801949a46e"
      },
      "outputs": [
        {
          "name": "stderr",
          "output_type": "stream",
          "text": [
            "/usr/local/lib/python3.11/dist-packages/pydantic/main.py:214: UserWarning: A custom validator is returning a value other than `self`.\n",
            "Returning anything other than `self` from a top level model validator isn't supported when validating via `__init__`.\n",
            "See the `model_validator` docs (https://docs.pydantic.dev/latest/concepts/validators/#model-validators) for more details.\n",
            "  warnings.warn(\n"
          ]
        }
      ],
      "source": [
        "from humanlayer.core.approval import HumanLayer\n",
        "hl = HumanLayer(api_key=humanlayer_api_key, verbose=True)\n",
        "\n",
        "\n",
        "# add can be called without approval\n",
        "def add(x: int, y: int) -> int:\n",
        "    \"\"\"Add two numbers together.\"\"\"\n",
        "    return x + y\n",
        "\n",
        "\n",
        "# but multiply must be approved by a human\n",
        "@hl.require_approval()\n",
        "def multiply(x: int, y: int) -> int:\n",
        "    \"\"\"multiply two numbers\"\"\"\n",
        "    return x * y"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "iTWKZwKp7UjO"
      },
      "source": [
        "Next we define the CAMEL agents, then run the computation commands. Here we will need to login HumanLayer cloud platform to approve for the agent to use the multiply function."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "5KsiJlRisi4g"
      },
      "source": [
        "![Screenshot 2025-01-17 at 17.57.48.png]()"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 15,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "3cW3hj3e7Y-1",
        "outputId": "3c977b4e-4c05-4da1-fee4-1bad6b6a371e"
      },
      "outputs": [
        {
          "name": "stderr",
          "output_type": "stream",
          "text": [
            "WARNING:camel.agents.chat_agent:Overriding the configured tools in `BaseModelBackend` with the tools from `ChatAgent`.\n"
          ]
        },
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "HumanLayer: waiting for approval for multiply via humanlayer cloud\n",
            "HumanLayer: human approved multiply\n",
            "\n",
            "\n",
            "----------Result----------\n",
            "\n",
            "\n",
            "2 multiplied by 5 is 10. Now, I need to add 32 to this result. So, 10 plus 32 equals 42.\n"
          ]
        }
      ],
      "source": [
        "from camel.toolkits import FunctionTool\n",
        "from camel.agents import ChatAgent\n",
        "from camel.models import ModelFactory\n",
        "from camel.types import ModelPlatformType, ModelType\n",
        "\n",
        "model = ModelFactory.create(\n",
        "    model_platform=ModelPlatformType.QWEN,\n",
        "    model_type=ModelType.QWEN_QWQ_32B,\n",
        ")\n",
        "\n",
        "tools = [FunctionTool(add), FunctionTool(multiply)]\n",
        "\n",
        "agent_with_tools = ChatAgent(\n",
        "    model = model,\n",
        "    tools=tools\n",
        ")\n",
        "\n",
        "# Interact with the agent\n",
        "response = agent_with_tools.step(\"multiply 2 and 5, then add 32 to the result\")\n",
        "print(\"\\n\\n----------Result----------\\n\\n\")\n",
        "print(response.msgs[0].content)\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Sx706ii3-PN2"
      },
      "source": [
        "## 🤖 Human-in-loop interaction"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "d1qi4mdb-d6P"
      },
      "source": [
        "Sometimes we want the agent to ask user during the working process, in this case, we can equip agent with human toolkits, and be able to ask human via console. This example demonstrates the human-in-loop function:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 23,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "xyujYUzN_M8Y",
        "outputId": "7c7473b3-a0df-4118-e71e-a1b15b833c80"
      },
      "outputs": [
        {
          "name": "stderr",
          "output_type": "stream",
          "text": [
            "WARNING:camel.agents.chat_agent:Overriding the configured tools in `BaseModelBackend` with the tools from `ChatAgent`.\n"
          ]
        },
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Question: What is the capital of France?\n",
            "Your reply: Paris\n",
            "You answered Paris, which is correct! The capital of France is indeed Paris. Great job! 🎉\n"
          ]
        }
      ],
      "source": [
        "from camel.toolkits import HumanToolkit\n",
        "human_toolkit = HumanToolkit()\n",
        "\n",
        "model = ModelFactory.create(\n",
        "    model_platform=ModelPlatformType.QWEN,\n",
        "    model_type=ModelType.QWEN_MAX,\n",
        ")\n",
        "\n",
        "agent = ChatAgent(\n",
        "    system_message=\"You are a helpful assistant.\",\n",
        "    model=model,\n",
        "    tools=[*human_toolkit.get_tools()],\n",
        ")\n",
        "\n",
        "response = agent.step(\n",
        "    \"Test me on the capital of some country, and comment on my answer.\"\n",
        ")\n",
        "\n",
        "print(response.msgs[0].content)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "flYNal6-R4yR"
      },
      "source": [
        "## 🌟 Highlights"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "SmkXhy4JR726"
      },
      "source": [
        "This notebook has guided you through setting up chat agents with the ability of **Human-in-loop** and **Human approval**.\n",
        "\n",
        "Key tools utilized in this notebook include:\n",
        "\n",
        "*   **CAMEL**: A powerful multi-agent framework that enables Retrieval-Augmented Generation and multi-agent role-playing scenarios, allowing for sophisticated AI-driven tasks.\n",
        "*   **HumanLayer**: HumanLayer is an API and SDK that enables AI Agents to contact humans for feedback, input, and approvals.\n",
        "*   **Human-in-loop**: The ability for agent to consult human during the execution of the task.\n",
        "*   **Human approval**: The ability for agent ask approval to execute some tasks.\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "7EZd8sutqorD"
      },
      "source": [
        "That's everything: Got questions about 🐫 CAMEL-AI? Join us on [Discord](https://discord.camel-ai.org)! Whether you want to share feedback, explore the latest in multi-agent systems, get support, or connect with others on exciting projects, we’d love to have you in the community! 🤝\n",
        "\n",
        "Check out some of our other work:\n",
        "\n",
        "1. 🐫 Creating Your First CAMEL Agent [free Colab](https://docs.camel-ai.org/cookbooks/create_your_first_agent.html)\n",
        "\n",
        "2.  Graph RAG Cookbook [free Colab](https://colab.research.google.com/drive/1uZKQSuu0qW6ukkuSv9TukLB9bVaS1H0U?usp=sharing)\n",
        "\n",
        "3. 🧑‍⚖️ Create A Hackathon Judge Committee with Workforce [free Colab](https://colab.research.google.com/drive/18ajYUMfwDx3WyrjHow3EvUMpKQDcrLtr?usp=sharing)\n",
        "\n",
        "4. 🔥 3 ways to ingest data from websites with Firecrawl & CAMEL [free Colab](https://colab.research.google.com/drive/1lOmM3VmgR1hLwDKdeLGFve_75RFW0R9I?usp=sharing)\n",
        "\n",
        "5. 🦥 Agentic SFT Data Generation with CAMEL and Mistral Models, Fine-Tuned with Unsloth [free Colab](https://colab.research.google.com/drive/1lYgArBw7ARVPSpdwgKLYnp_NEXiNDOd-?usp=sharingg)\n",
        "\n",
        "Thanks from everyone at 🐫 CAMEL-AI\n",
        "\n",
        "\n",
        "<div class=\"align-center\">\n",
        "  <a href=\"https://www.camel-ai.org/\"><img src=\"https://i.postimg.cc/KzQ5rfBC/button.png\"width=\"150\"></a>\n",
        "  <a href=\"https://discord.camel-ai.org\"><img src=\"https://i.postimg.cc/L4wPdG9N/join-2.png\"  width=\"150\"></a></a>\n",
        "  \n",
        "⭐ <i>Star us on [*Github*](https://github.com/camel-ai/camel), join our [*Discord*](https://discord.camel-ai.org) or follow our [*X*](https://x.com/camelaiorg)\n",
        "</div>"
      ]
    }
  ],
  "metadata": {
    "colab": {
      "provenance": []
    },
    "kernelspec": {
      "display_name": "Python 3",
      "name": "python3"
    },
    "language_info": {
      "name": "python"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}
